using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Linq;

namespace WMVConvert.Metadata
{
	public enum TimeStampFormat
	{
		AbsoluteFrame = 1, // Time stamps are 32-bit values containing the absolute time of the lyric in frame numbers. 
		AbsoluteMillisecond = 2 // Time stamps are 32-bit values containing the absolute time of the lyric in milliseconds 
	}

	public enum ContentType
	{
		Strings = 0, // Synchronized strings other than the types listed in this table 
		SongLyrics = 1, // Song lyrics 
		TextTranscription = 2, // Text transcription 
		Names = 3, // Names of parts of the content. For example, movements of classical pieces, like "Adagio" 
		Events = 4, // Events, such as stage directions in operas 
		ChordNotations = 5, // Chord notations 
		TriviaInformation = 6, // Trivia information 
		WebURLs = 7, // URLs to Web pages 
		ImagesURLs = 8, // URLs to images 
	}

	[StructLayout(LayoutKind.Sequential)]
	public class Syllable
	{
		[MarshalAs(UnmanagedType.LPWStr)]
		private string text;
		[MarshalAs(UnmanagedType.I4)]
		private int timeStamp;

		public const string TerminatorString = " ";

		public Syllable(int timeStamp)
			: this(TerminatorString, timeStamp)
		{
		}

		public Syllable(string text, int timeStamp)
		{
			this.text = text;
			this.timeStamp = timeStamp;
		}

		public string Text
		{
			get { return text; }
		}

		public int TimeStamp
		{
			get { return timeStamp; }
		}

		public int Size
		{
			get
			{
				return ( text.Length + 1 ) * sizeof(char) + sizeof(int);
			}
		}
	}

	public class WMSynchronisedLyrics : WMBinary<Structures.WM_SynchronisedLyrics>
	{
		private TimeStampFormat timeStampFormat;
		private ContentType contentType;
		private string contentDescriptor;
		private IEnumerable<Syllable> lyrics;
		public const ContentType ContentTypeDefault = ContentType.SongLyrics;
		public const TimeStampFormat TimeStampFormatDefault = TimeStampFormat.AbsoluteMillisecond;
		public const string ContentDescriptorDefault = "SongLyrics";

		public WMSynchronisedLyrics(string fileName)
			: this(ContentDescriptorDefault, TimeStampFormatDefault, ContentTypeDefault, Enumerable.Empty<Syllable>())
		{
		}

		public WMSynchronisedLyrics(IntPtr pValue, int valueLength)
		{
			throw new NotImplementedException();
		}

		public WMSynchronisedLyrics(IEnumerable<Syllable> lyrics)
			: this(ContentDescriptorDefault, TimeStampFormatDefault, ContentTypeDefault, lyrics)
		{
		}

		public WMSynchronisedLyrics(ContentType contentType, IEnumerable<Syllable> lyrics)
			: this(ContentDescriptorDefault, TimeStampFormatDefault, contentType, lyrics)
		{
		}

		public WMSynchronisedLyrics(string description, ContentType contentType, IEnumerable<Syllable> lyrics)
			: this(description, TimeStampFormatDefault, contentType, lyrics)
		{
		}

		public WMSynchronisedLyrics(TimeStampFormat timeFormat, IEnumerable<Syllable> lyrics)
			: this(ContentDescriptorDefault, timeFormat, ContentTypeDefault, lyrics)
		{
		}

		public WMSynchronisedLyrics(string description, TimeStampFormat timeFormat, IEnumerable<Syllable> lyrics)
			: this(description, timeFormat, ContentTypeDefault, lyrics)
		{
		}

		public WMSynchronisedLyrics(string descriptor,TimeStampFormat timeStampFormat, ContentType contentType, IEnumerable<Syllable> lyrics)
		{
			this.timeStampFormat = timeStampFormat;
			this.contentType = contentType;
			this.contentDescriptor = descriptor;
			this.lyrics = lyrics;
		}

		private void Write(List<Syllable> list)
		{
			int size = 0;
			list.ForEach(delegate(Syllable s)
			{
				size += s.Size;
			});
			//Write(size);
			if (size > 0)
			{
				IntPtr pList = Alloc(list, size);
				//Write(pList);
				list.ForEach(delegate(Syllable s)
				{
					Marshal.Copy(s.Text.ToCharArray(), 0, pList, s.Text.Length);
					Marshal.WriteInt16(pList, s.Text.Length * sizeof(char), 0);
					Marshal.WriteInt32(pList, s.Size - sizeof(int), s.TimeStamp);
					pList = new IntPtr(pList.ToInt32() + s.Size);
				});
			}
		}

		protected override Structures.WM_SynchronisedLyrics GetData()
		{
			throw new NotImplementedException();
		}
	}
}
